/*  

Cafechess Library: Cover basic chess programming needs, like GUI, Engine integration, 
FEN and PGN parsing.

                 \\|//
                 (o o)
--------------ooO-(_)-Ooo----------------------------------
Copyright (C) 2009  By Gregory A. Prentice Snoqualmie, WA
                    www.cafechess.org
                    cafechess@comcast.net
                      Oooo
--------------oooO----(  )---------------------------------
              (  )    (_/
               \_)

Microsoft Public License (Ms-PL)
               
Revisions:

Author        Date    Description:

*/
using System;
using System.Threading;

namespace Cafechess.Threading
{
  /// <summary>
  /// Semaphore implements a counting semaphore with single ownership semantics.
  /// </summary>
  public class Semaphore : AbstractSemaphore
  {
    /// <summary>
    /// Overloaded constructor.  Initializes the semaphore with a maximum acquisition count.
    /// The minimum and maximum acquisition counts are the same, so the semaphore is
    /// created with just one blocking condition - an upper boundary on the number of
    /// calls to <code>P()</code>.
    /// </summary>
    /// 
    /// <param name="nAcquisitionCount">
    /// The maximum number of resources that can be acquired before the next caller of
    /// <code>P()</code> blocks.
    /// </param>
    public Semaphore( int nAcquisitionCount ) : base( nAcquisitionCount, nAcquisitionCount )
    {
    }

    /// <summary>
    /// Default constructor.  Initializes the semaphore with a max resource count of zero.
    /// Thus an immediate call to <code>P()</code> will block the calling thread.
    /// The minimum resource count is infinite, and thus a call to <code>V()</code> always
    /// wakes up the next blocked thread, yet still tracking the number of calls to <code>V()</code>.
    /// </summary>
    public Semaphore() : base( Int32.MaxValue, 0 )
    {
    }

    /// <summary>
    /// Resets the semaphore's acquisition count and resumes all blocked threads.
    /// </summary>
    public override void Reset()
    {
      lock( this ) 
      {
        cnCount = 0;
        Monitor.PulseAll( this );
      }
    }
  }
}
